package web.java.a_BeanUtils;

import java.lang.reflect.InvocationTargetException;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

import org.apache.commons.beanutils.BeanUtils;
import org.apache.commons.beanutils.ConvertUtils;
import org.apache.commons.beanutils.Converter;
import org.apache.commons.beanutils.locale.converters.DateLocaleConverter;
import org.junit.Test;

class MyConverter implements Converter{

	@Override
	public Object convert(Class type, Object value) {
		if(type!=Date.class){
			//如果参数不是Date类型，则输出null
			return null;
		}
		if(value == null || "".equals(value.toString().trim())){
			//若参数为null或空字符串或者是一串空格，则返回null
			return null;
		}
		try{
			//实现字符串转化为日期类型
			SimpleDateFormat format=new SimpleDateFormat("yyyy-MM-dd");
			return format.parse(value.toString());
		}catch(ParseException e){
			throw new RuntimeException(e);
		}
	}
}
	

public class Demo01_Base {

	/**
	 * BeanUtils组件
	 * */
	@Test
	public void base() throws Exception, InvocationTargetException{
		/**
		 * 1、基本操作
		 * */
		//传统set方法给属性赋值
		Admin admin1=new Admin();
		admin1.setId(100);
		admin1.setName("cainter");
		System.out.println(admin1);
		
		//使用BeanUtils组件实现赋值，又叫实现对象属性的拷贝
		Admin admin2=new Admin();
		BeanUtils.copyProperty(admin2, "name", "monster");
		
		//BeanUtils可以自动进行类型转换
		
		//BeanUtils.copyProperty(admin2, "id", 200);
		BeanUtils.copyProperty(admin2,"id","500");
		BeanUtils.copyProperty(admin2, "date", new Date());
		System.out.println(admin2);
		/**
		 * 2、实现对象的拷贝
		 * 	将同一个类的对象属性全部拷贝到另一个对象
		 * 	注意：当原对象中存在空值(null)时，无法拷贝，在Test中不报错
		 * */
		Admin newAdmin=new Admin();
		BeanUtils.copyProperties(newAdmin,admin2);
		System.out.println(newAdmin);
		/**
		 * 3、map数据拷贝到对象中
		 * 	在Servlet中，接收页面的数据，可以使用request.getParameterMap();来将页面的数据封装入Map集合中，
		 * 	从而可以直接一次性copy给对象
		 * */
		Map<String,Object> map=new HashMap<String,Object>();
		map.put("id", 1);
		map.put("name", "master");
		map.put("date", new Date());
		//注意：map中的键(key)要保持和对象中的属性一致
		Admin mapAdmin=new Admin();
		BeanUtils.populate(mapAdmin, map);
		System.out.println(mapAdmin);
	}
	/**
	 * 4、日期类型的拷贝
	 *  1. 注册日期类型转换器 ConvertUtils.register(Convert convert, String date);
	 *  2. 自定义方式(new Convert)或使用系统默认(DateLocaleConverter)
	 *  2. 将字符型日期(String)转换为日期型(Date)
	 * 这里自定义的日期转换类，也可以将字符串转化为其他类型。
	 * @throws InvocationTargetException 
	 * @throws IllegalAccessException 
	 * */
	@Test
	public void selfDefined() throws IllegalAccessException, InvocationTargetException{
		/* a 自定义日期类型转换器 
		 * 	两个参数
		 * 	1、转换器类，这里是自定义，需要重写接口中的方法
		 * 	2、转换后的数据类型的字节码，这里是Date.class
		 * */
		Admin dateAdmin=new Admin();
		int id=2;
		String name="洛宇";
		String date1="1992-04-07";
		String date2="";
		String date3=null;
		String date4="     ";
		//date2，date3，date4输出都是null，与自定义中convert的方法返回结果一致
		MyConverter dateConverter=new MyConverter();
		ConvertUtils.register(dateConverter, Date.class);
		//将字符串的时间添加到对象中，自动转化为Date类型
		BeanUtils.copyProperty(dateAdmin,"id",id);
		BeanUtils.copyProperty(dateAdmin,"name",name);
		BeanUtils.copyProperty(dateAdmin,"date",date1);
		System.out.println(dateAdmin);
	}
	@Test
	public void sysDefined() throws IllegalAccessException, InvocationTargetException{
		/* b 通过BeanUtils提供的日期类型转换器工具进行转换(DateLocaleConverter)
		 * */
		Admin dateAdmin=new Admin();
		int id=2;
		String name="洛宇";
		String date1="1992-04-07";
		String date2="1992-04-07 23:35:12";
		String date3=null;
		String date4="     ";
		//只是识别date1，date3，也许可以增加时分秒，具体格式还得看源码，当日期出错，则添加失败，在Test里不返回任何值
		//总体来说，不是很实用
		ConvertUtils.register(new DateLocaleConverter(),Date.class);
		//转换并添加
		BeanUtils.copyProperty(dateAdmin,"id",id);
		BeanUtils.copyProperty(dateAdmin,"name",name);
		BeanUtils.copyProperty(dateAdmin,"date",date1);
		System.out.println(dateAdmin);
	}
}
